<?php
/**
*
  +------------------------------------+
  | BitLF [ FAST DEVELOP KIT ]         |
  +------------------------------------+
  | 2010-2016 (c)                      |
  +------------------------------------+
  | Author: amamatthew                 |
  +------------------------------------+
* 日    期：2017-08-06
* 版    本：1.0.0
* 功能说明：加密工具类。
**/
namespace app\common\sdk;

class PassHash {

  /**
   * 密码散列加密PHP5.5版本以上使用
   *
   * [string] $password：    初始密码
   * [string] $arithmetic： 加密算法
   * @return [string]       加密字符串
   */
  public static function password_hash( $password ) {
      return password_hash($password, PASSWORD_DEFAULT);
    }
  /**
   * 验证PHP5.5版本以上使用
   * [string] $password：   待验证密码
   * [string] $arithmetic： 加密后的密码串
   * @return [bool]         密码是否匹配
   */
  public static function password_verify( $password, $hash ) {
      return password_verify($password, $hash);
  }
  /**
   * 字符串对称加密程序,可以设置密钥（key）和过期时间
   * [string] $string：    明文或密文
   * [string] $operation： DECODE表示解密,其它表示加密
   * [string] $key：       密匙
   * [int]    $expiry：    密文有效期(秒)
   * @return [string]      加密后的字符串或者是解密后的源字符串
   * @example
   *
   *     $a = authcode('abc', 'ENCODE', 'key');
   *     $b = authcode($a, 'DECODE', 'key'); // $b(abc)
   *
   *     $a = authcode('abc', 'ENCODE', 'key', 3600);
   *     $b = authcode('abc', 'DECODE', 'key'); // 在一个小时内，$b(abc)，否则 $b 为空
   */

  public static function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {

    $ckey_length = 4;

    //$GLOBALS方法获取全局秘钥

    $key = md5($key != '' ? $key : $GLOBALS['discuz_auth_key']);

    $keya = md5(substr($key, 0, 16));
    $keyb = md5(substr($key, 16, 16));
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()) , -$ckey_length)) : '';

    $cryptkey = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb) , 0, 16) . $string;
    $string_length = strlen($string);
    $result = '';
    $box = range(0, 255);
    $rndkey = array();

    for ($i = 0; $i <= 255; $i++) {
      $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }

    for ($j = $i = 0; $i < 256; $i++) {
      $j = ($j + $box[$i] + $rndkey[$i]) % 256;
      $tmp = $box[$i];
      $box[$i] = $box[$j];
      $box[$j] = $tmp;
    }

    for ($a = $j = $i = 0; $i < $string_length; $i++) {
      $a = ($a + 1) % 256;
      $j = ($j + $box[$a]) % 256;
      $tmp = $box[$a];
      $box[$a] = $box[$j];
      $box[$j] = $tmp;
      $result.= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }

    if ($operation == 'DECODE') {
      if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb) , 0, 16)) {
        return substr($result, 26);
      } else {
        return '';
      }
    } else {
      return $keyc . str_replace('=', '', base64_encode($result));
    }
  }
}